Everglades Historical GIS Analysis

Smuggling Routes, Hidden Sites & the 1978 Coastline

Author

Ryan Lafferty

Published

February 10, 2026

The Outlaw Coast

For nearly a century, the Ten Thousand Islands have served as Florida’s untamed backdoor—a labyrinth of mangrove tunnels and oyster bars where the only law was the tide. In the 1920s, this “watery wilderness” became a haven for rum-runners who used the shallow, shifting channels to evade heavy Federal cutters, turning the quiet fishing villages of Chokoloskee and Everglades City into covert ports of call for Caribbean liquor. But the skills forged in that era—navigating the pitch-black backcountry without a chart—found a new purpose in the 1970s. As commercial fishing was restricted and the local economy cratered, the sons and grandsons of those early pioneers became “saltwater cowboys,” swapping mullet for marijuana. Under the cover of the mangrove canopy, they transformed these islands into one of the primary entry points for the “Square Grouper” era, hauling millions of pounds of contraband through a landscape that swallowed outsiders whole.


Points of Interest

Show code
import sys, platform
sys.path.append("..")

import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt

from db_connection import query_to_geodataframe, query_to_dataframe
from map_builder import create_base_map, add_geodataframe_layer, add_point_markers, finalize_map

# Historical sites — already SRID 4326
sites = query_to_geodataframe("""
    SELECT id, name, description, site_type, year_established,
           significance_level, latitude, longitude, geom
    FROM historical_sites
""")

print(f"{len(sites)} historical sites loaded")

# Display table — drop significance_level, widen description
display_cols = sites[["name", "site_type", "year_established", "description"]].copy()
display_cols.columns = ["Name", "Type", "Year", "Description"]
display_cols.style.set_properties(
    subset=["Description"], **{"min-width": "350px", "white-space": "normal"}
)
20 historical sites loaded
  Name Type Year Description
0 Ted Smallwood Store Trading Post 1906 Historic trading post; central hub for locals, outlaws, and early trade.
1 Everglades City Center Town Center 1873 Epicenter of "Operation Everglades" (1983); the town where ~80% of the male population was arrested.
2 Watson's Place (Chatham Bend) Homestead 1890 Site of the Ed Watson homestead; represents the area's deep history of lawlessness and isolation.
3 Chokoloskee Island Settlement 1874 The primary island community connected to the mainland; home to Totch Brown.
4 Fakahatchee Strand State Preserve Preserve 1974 Historic logging area often used for clandestine airstrips due to its remote, linear features.
5 Smallwood's Dock Dock 1906 Original dock where supplies arrived by boat; critical supply line for the island.
6 Chevelier Bay Bay 1920 Historic fishing grounds and smuggling route during Prohibition era.
7 Lopez River Waterway 1920 Remote waterway used for rum-running and later marijuana smuggling operations.
8 Turner River Waterway 1930 Historic canal and transportation route through the mangroves.
9 Halfway Creek Creek 1910 Midpoint stop for traders between Everglades City and the outer islands.
10 Indian Key Pass Pass 1500 Historic Calusa Indian site and later smuggling route.
11 Pavilion Key Island 1900 Remote island used as a camp by fishermen and later as a drop point.
12 Rabbit Key Island 1920 Small key used for temporary camps and clandestine meetings.
13 Mormon Key Island 1880 Historic farming attempt site; represents failed settlement efforts.
14 Lostmans River Waterway 1890 Extremely remote waterway; site of Ed Watson murders and ongoing lawlessness.
15 Shark River Waterway 1800 Major waterway through the Everglades; historic Seminole route.
16 Flamingo Settlement 1893 Remote outpost at the southern tip; historic fishing village.
17 Cape Sable Cape 1838 Southernmost point; historic lighthouse and remote settlement.
18 Whitewater Bay Bay 1900 Large shallow bay; historic fishing grounds and smuggling route.
19 Oyster Bay Bay 1890 Historic oyster harvesting area; important food source.

The Smuggler’s Highway

To the uninitiated, the map of the Ten Thousand Islands is a chaotic splatter of green and blue, but to the smugglers, it was a precise network of arterial highways. The Barron River, the region’s dredged commercial heart, served as the brazen front door where shrimp boats laden with bales would dock under the guise of a night’s catch. Deeper in the backcountry lay the Chatham River, a historic channel echoing with the dark legacy of Edgar Watson, offering a direct, deep-water vein to the hidden interiors of the Glades. To the south, the Lopez River provided a winding “back alley” for smaller skiffs to slip unnoticed into the labyrinth, while the Wilderness Waterway—now a celebrated paddling trail—served as the “Inside Route,” a 99-mile concealed highway allowing traffickers to move illicit cargo from the Cape Romano shoals all the way to Flamingo without ever exposing themselves to the open Gulf or the Coast Guard’s gaze.


Route Details

Show code
# Historical routes — already SRID 4326
routes = query_to_geodataframe("""
    SELECT id, name, description, route_type, year_active, length_km, geom
    FROM historical_routes
""")

print(f"{len(routes)} routes loaded")
routes[["name", "route_type", "year_active", "length_km", "description"]]
4 routes loaded
name route_type year_active length_km description
0 Barron River Route Water Route 1900 6.22 Main water route from Everglades City to Choko...
1 Chatham River Route Water Route 1890 17.60 Water route from Chokoloskee to Watson's Place...
2 Lopez River Smuggling Route Smuggling Route 1920 7.57 Historic rum-running and later marijuana smugg...
3 Wilderness Waterway (North Section) Water Route 1900 105.47 Historic route through the Ten Thousand Island...

Smuggling Routes & Historical Sites

All layers on one interactive satellite map: the 1978 coastline, smuggling routes, and historical sites.

Show code
import folium

# Load coastline — transform SRID 4269 → 4326 for web maps
coastline = query_to_geodataframe("""
    SELECT
        ogc_fid,
        inform,
        attribute,
        class,
        ST_Transform(wkb_geometry, 4326) AS geom
    FROM "1978_fl_coastline"
""", geom_col="geom", crs=4326)

print(f"Coastline: {len(coastline)} features")

# Base map — satellite imagery centered on Ten Thousand Islands
m = create_base_map(center=[25.85, -81.35], zoom=10, tiles="satellite")

# --- Coastline layer (styled for satellite contrast) ---
shoreline = coastline[coastline["class"] == "SHORELINE"]
alongshore = coastline[coastline["class"] == "ALONGSHORE FEATURE"]

m = add_geodataframe_layer(
    m, shoreline,
    name="Shoreline (1978)",
    tooltip_fields=["inform", "attribute"],
    style={"color": "#38bdf8", "weight": 1.5, "opacity": 0.8},
)

m = add_geodataframe_layer(
    m, alongshore,
    name="Alongshore Features (1978)",
    tooltip_fields=["inform", "attribute"],
    style={"color": "#94a3b8", "weight": 1, "opacity": 0.6},
)

# --- Routes layer (amber/gold for satellite visibility) ---
m = add_geodataframe_layer(
    m, routes,
    name="Historical Routes",
    tooltip_fields=["name", "route_type", "year_active"],
    style={"color": "#fbbf24", "weight": 4, "opacity": 0.9, "dashArray": "8 4"},
    highlight={"weight": 6, "opacity": 1},
)

# --- Sites layer (wider popups, larger markers) ---
for _, site in sites.iterrows():
    color = "#f43f5e" if site["significance_level"] == "High" else (
            "#f97316" if site["significance_level"] == "Medium" else "#0ea5e9")

    folium.CircleMarker(
        location=[site["latitude"], site["longitude"]],
        radius=9 if site["significance_level"] == "High" else 6,
        color=color,
        fill=True,
        fill_opacity=0.8,
        tooltip=f"<b>{site['name']}</b> ({site['year_established']})",
        popup=folium.Popup(
            f"<div style='min-width:280px'>"
            f"<b>{site['name']}</b><br>"
            f"<i>{site['site_type']}</i> — {site['year_established']}<br><br>"
            f"{site['description']}"
            f"</div>",
            max_width=450,
        ),
    ).add_to(m)

m = finalize_map(m)
m
Coastline: 5689 features
Make this Notebook Trusted to load map: File -> Trust Notebook

Coastline Overview

Show code
# Filter out CARTOGRAPHIC LIMIT for a cleaner legend
coastline_display = coastline[coastline["class"] != "CARTOGRAPHIC LIMIT"]

fig, ax = plt.subplots(1, 1, figsize=(12, 8))

coastline_display.plot(
    ax=ax,
    column="class",
    legend=True,
    legend_kwds={"loc": "lower left", "fontsize": 8},
    linewidth=0.5,
)
ax.set_title("1978 Florida Coastline by Classification", fontsize=14)
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
plt.tight_layout()
plt.show()


Sites Timeline

Show code
import plotly.express as px

fig = px.scatter(
    sites,
    x="year_established",
    y="name",
    color="significance_level",
    symbol="site_type",
    title="Historical Sites — Timeline",
    labels={"year_established": "Year Established", "name": "Site"},
    color_discrete_map={"High": "#f43f5e", "Medium": "#f97316", "Low": "#0ea5e9"},
)
fig.update_layout(height=500)
fig.show()

Documentation & Source Data

The following sources document the historical routes and smuggling operations mapped in this analysis.

1. Barron River Route

Significance: The primary commercial artery. The 1983 “Operation Everglades” blockade physically shut down the only road (CR 29) and the river access to trap the smugglers.

  • Primary: United States District Court, Middle District of Florida. “Operation Everglades” Case Archives (1983–1984).
  • Secondary: Deep Water: The Story of the Beavers of Everglades City (Local history covering the dredging and subsequent bust).

2. Chatham River Route

Significance: Historically the deep-water access to the Watson Place. Smugglers used the high banks of the Chatham (rare in the mangroves) to offload onto higher ground (shell mounds).

  • Primary: Tebeau, Charlton W. Man in the Everglades: 2000 Years of Human History in the Everglades National Park. University of Miami Press.
  • Literary/Historical: Matthiessen, Peter. Killing Mister Watson. (Documents the river as the primary transit route for the region’s outlaws).

3. Lopez River Route

Significance: Named for the Lopez family (early settlers). It connects the inland bays to the Gulf, allowing for “inside” passage to avoid rough seas and patrols.

  • Primary: Simons, M.H. “Report on the Ten Thousand Islands.” Annual Report of the Smithsonian Institution.
  • Contextual: Brown, Totch. Totch: A Life in the Everglades. (Describes the specific use of these “backdoor” family channels for evading game wardens and later drug interdiction).

4. Wilderness Waterway (North Section)

Significance: The historic “Inside Route.” While officially established as a park trail in the 1970s, its channels were the standard “smuggler’s highway” to move goods between Everglades City and Flamingo without entering the Gulf of Mexico.

  • Primary: Truesdell, William G. A Guide to the Wilderness Waterway of the Everglades National Park. University of Miami Press.
  • Oral History: “Calusa to Campbell” (NPS Historic Resource Study) – details the usage of the inland cuts by locals to avoid “outside” detection.

Video Reference

Everglades City, Florida’s Bootlegging Capital — This video explicitly connects the 1920s rum-running era to the 1980s drug trade, illustrating how the same local families and geography facilitated both eras of smuggling.


Technical Details

Environment

Show code
print("Python:", sys.version.split()[0])
print("Platform:", platform.platform())
print("GeoPandas:", gpd.__version__)
print("Pandas:", pd.__version__)
Python: 3.11.9
Platform: Windows-10-10.0.26100-SP0
GeoPandas: 1.1.2
Pandas: 2.2.2

Coastline Data

Show code
print(f"Total features: {len(coastline)}")
print(f"CRS: {coastline.crs}")
coastline.head()
Total features: 5689
CRS: EPSG:4326
ogc_fid inform attribute class geom
0 1 Jetty/Brkwater/Groin Jetty.Bare ALONGSHORE FEATURE MULTILINESTRING ((-81.91294 26.42877, -81.9128...
1 2 Apparent Shore Natural.Apparent.Mangrove Or Cypress SHORELINE MULTILINESTRING ((-81.88204 26.43101, -81.882 ...
2 3 Apparent Shore Natural.Apparent.Mangrove Or Cypress SHORELINE MULTILINESTRING ((-81.87071 26.43337, -81.8707...
3 4 Apparent Shore Natural.Apparent.Mangrove Or Cypress SHORELINE MULTILINESTRING ((-81.83806 26.43486, -81.8379...
4 5 Pier, Ramp, or Dock Pier ALONGSHORE FEATURE MULTILINESTRING ((-81.91804 26.43772, -81.9181...

Feature Breakdown

Show code
class_counts = (
    coastline.groupby("class")
    .size()
    .reset_index(name="count")
    .sort_values("count", ascending=False)
)
class_counts
class count
2 SHORELINE 4884
0 ALONGSHORE FEATURE 796
1 CARTOGRAPHIC LIMIT 9
Show code
inform_counts = (
    coastline.groupby("inform")
    .size()
    .reset_index(name="count")
    .sort_values("count", ascending=False)
)
inform_counts
inform count
0 Apparent Shore 3704
3 Gen. manmade object 783
5 Pier, Ramp, or Dock 685
6 SPOR 372
4 Jetty/Brkwater/Groin 108
1 Approx. Shore 23
7 User added line 9
2 Approximate Shore 2

Notes / Decision Log

  • Data sources: PostgreSQL/PostGIS everglades_gis database
  • CRS choices: Coastline transformed from SRID 4269 (NAD83) → 4326 (WGS84) via ST_Transform in the SQL query. Routes and sites are already 4326.
  • Assumptions: Coastline features classified as SHORELINE vs ALONGSHORE FEATURE based on the class column from the original NOAA data. CARTOGRAPHIC LIMIT features filtered from the static map legend.
  • Next steps: Overlay additional historical data; filter coastline to Everglades/Ten Thousand Islands extent for performance.

Built with Quarto • Template: Quarto GIS Research Starter